package ltd.flyweight.liquibasehelper.module.jzgk.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import liquibase.change.ColumnConfig;
import liquibase.change.core.InsertDataChange;
import liquibase.change.core.UpdateDataChange;
import liquibase.changelog.ChangeSet;
import liquibase.serializer.core.yaml.YamlChangeLogSerializer;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.dbservice.JzgkSysDictDataDbService;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.dbservice.JzgkSysDictDataExtensionDbService;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.dbservice.JzgkSysDictTypeDbService;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.dbservice.JzgkSysDictTypeExtensionDbService;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.entity.JzgkSysDictDataEntity;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.entity.JzgkSysDictDataExtensionEntity;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.entity.JzgkSysDictTypeEntity;
import ltd.flyweight.liquibasehelper.module.jzgk.dao.entity.JzgkSysDictTypeExtensionEntity;
import ltd.flyweight.liquibasehelper.module.zngk.dao.dbservice.ZngkSysDictDataDbService;
import ltd.flyweight.liquibasehelper.module.zngk.dao.dbservice.ZngkSysDictDataExtensionDbService;
import ltd.flyweight.liquibasehelper.module.zngk.dao.dbservice.ZngkSysDictTypeDbService;
import ltd.flyweight.liquibasehelper.module.zngk.dao.dbservice.ZngkSysDictTypeExtensionDbService;
import ltd.flyweight.liquibasehelper.module.zngk.dao.entity.ZngkSysDictDataEntity;
import ltd.flyweight.liquibasehelper.module.zngk.dao.entity.ZngkSysDictDataExtensionEntity;
import ltd.flyweight.liquibasehelper.module.zngk.dao.entity.ZngkSysDictTypeEntity;
import ltd.flyweight.liquibasehelper.module.zngk.dao.entity.ZngkSysDictTypeExtensionEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class JzgkSysDictService {

    private final JzgkSysDictTypeDbService jzgkSysDictTypeDbService;

    private final JzgkSysDictTypeExtensionDbService jzgkSysDictTypeExtensionDbService;

    private final JzgkSysDictDataDbService jzgkSysDictDataDbService;

    private final JzgkSysDictDataExtensionDbService jzgkSysDictDataExtensionDbService;

    private final ZngkSysDictTypeDbService zngkSysDictTypeDbService;

    private final ZngkSysDictTypeExtensionDbService zngkSysDictTypeExtensionDbService;

    private final ZngkSysDictDataDbService zngkSysDictDataDbService;

    private final ZngkSysDictDataExtensionDbService zngkSysDictDataExtensionDbService;

    @SneakyThrows
    public void runTaskGenDictTypeAndDataLiquibaseYmlScript(String dictType, String newDictId) {
        JzgkSysDictTypeEntity dictTypeEntity = jzgkSysDictTypeDbService.getOne(
                Wrappers
                        .lambdaQuery(JzgkSysDictTypeEntity.class)
                        .eq(JzgkSysDictTypeEntity::getDictType, dictType)
        );
        log.info("dictTypeEntity={}", dictTypeEntity);
        List<JzgkSysDictDataEntity> dictDataEntityList = jzgkSysDictDataDbService.list(
                Wrappers
                        .lambdaQuery(JzgkSysDictDataEntity.class)
                        .eq(JzgkSysDictDataEntity::getDictType, dictType)
                        .orderByAsc(
                                JzgkSysDictDataEntity::getDictSort,
                                JzgkSysDictDataEntity::getDictValue,
                                JzgkSysDictDataEntity::getDictLabel,
                                JzgkSysDictDataEntity::getDictCode
                        )
        );
        log.info("dictDataEntityList={}", dictDataEntityList);

        ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-01")), "周立山", false, false, null, null, null, true, null);
        changeSet.setComments("sys_dict_type增加%s字典".formatted(dictTypeEntity.getDictName()));
        InsertDataChange insertDictTypeChange = new InsertDataChange();
        insertDictTypeChange.setTableName("sys_dict_type");
        insertDictTypeChange.addColumn(ColumnConfig.fromName("dict_id").setValue(newDictId));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("tenant_id").setValue(dictTypeEntity.getTenantId()));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("dict_name").setValue(dictTypeEntity.getDictName()));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("dict_type").setValue(dictType));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("create_dept").setValue(dictTypeEntity.getCreateDept().toString()));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("create_by").setValue(dictTypeEntity.getCreateBy().toString()));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("create_time").setValue("now()"));
        insertDictTypeChange.addColumn(ColumnConfig.fromName("remark").setValue(dictTypeEntity.getDictName()));
        changeSet.addChange(insertDictTypeChange);
        int i = 0;
        for (JzgkSysDictDataEntity JzgkSysDictDataEntity : dictDataEntityList) {
            i++;
            InsertDataChange insertDictDataChange = new InsertDataChange();
            insertDictDataChange.setTableName("sys_dict_data");
            insertDictDataChange.addColumn(ColumnConfig.fromName("dict_code").setValue("%s%02d".formatted(newDictId, i)));
            insertDictDataChange.addColumn(ColumnConfig.fromName("tenant_id").setValue(dictTypeEntity.getTenantId()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("dict_sort").setValue(JzgkSysDictDataEntity.getDictSort().toString()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("dict_label").setValue(JzgkSysDictDataEntity.getDictLabel()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("dict_value").setValue(JzgkSysDictDataEntity.getDictValue()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("dict_type").setValue(JzgkSysDictDataEntity.getDictType()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("list_class").setValue(JzgkSysDictDataEntity.getListClass()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("is_default").setValue(JzgkSysDictDataEntity.getIsDefault()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("create_dept").setValue(dictTypeEntity.getCreateDept().toString()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("create_by").setValue(dictTypeEntity.getCreateBy().toString()));
            insertDictDataChange.addColumn(ColumnConfig.fromName("create_time").setValue("now()"));
            insertDictDataChange.addColumn(ColumnConfig.fromName("remark").setValue(JzgkSysDictDataEntity.getRemark()));
            changeSet.addChange(insertDictDataChange);
        }

        // 创建YAML序列化器
        YamlChangeLogSerializer serializer = new YamlChangeLogSerializer();
        try (OutputStream outputStream = new FileOutputStream("dict_%s.yml".formatted(dictType))) {
            serializer.write(List.of(changeSet), outputStream);
        }
    }

    @SneakyThrows
    public void full() {
        // 需要忽略的字典
        Set<String> willIgnoredSysDictTypes = new LinkedHashSet<>();
        willIgnoredSysDictTypes.add("sys_user_sex");
        willIgnoredSysDictTypes.add("sys_show_hide");
        willIgnoredSysDictTypes.add("sys_normal_disable");
        willIgnoredSysDictTypes.add("sys_yes_no");
        willIgnoredSysDictTypes.add("sys_notice_type");
        willIgnoredSysDictTypes.add("sys_notice_status");
        willIgnoredSysDictTypes.add("sys_oper_type");
        willIgnoredSysDictTypes.add("sys_common_status");
        willIgnoredSysDictTypes.add("sys_grant_type");
        willIgnoredSysDictTypes.add("sys_device_type");
        willIgnoredSysDictTypes.add("sys_region_type");
        willIgnoredSysDictTypes.add("sys_user_type");
        willIgnoredSysDictTypes.add("sys_dept_type");
        willIgnoredSysDictTypes.add("sys_dict_extension_data_type");
        willIgnoredSysDictTypes.add("sys_app_type");
        // 这几个比较特殊
        willIgnoredSysDictTypes.add("dept_type");

        willIgnoredSysDictTypes.add("building_category_type");
        willIgnoredSysDictTypes.add("equipment_category_classification");
        willIgnoredSysDictTypes.add("violation_dimension");
        willIgnoredSysDictTypes.add("limit_level");
        willIgnoredSysDictTypes.add("control_risk_value_type");
        willIgnoredSysDictTypes.add("control_risk_evaluate_type");
        willIgnoredSysDictTypes.add("control_measures_type");
        willIgnoredSysDictTypes.add("biz_violation_check_rectify_status");
        willIgnoredSysDictTypes.add("rectify_period");
        willIgnoredSysDictTypes.add("dict_status");
        willIgnoredSysDictTypes.add("service_status");
        willIgnoredSysDictTypes.add("dept_category");
//'sys_user_sex',
//'sys_show_hide',
//'sys_normal_disable',
//'sys_yes_no',
//'sys_notice_type',
//'sys_notice_status',
//'sys_oper_type',
//'sys_common_status',
//'sys_grant_type',
//'sys_device_type',
//'sys_region_type',
//'sys_user_type',
//'sys_dept_type',
//'sys_dict_extension_data_type',
//'sys_app_type',
//'dept_type',
//'building_category_type',
//'equipment_category_classification',
//'violation_dimension',
//'limit_level',
//'control_risk_value_type',
//'control_risk_evaluate_type',
//'control_measures_type',
//'biz_violation_check_rectify_status',
//'rectify_period',
//'dict_status',
//'service_status',
//'dept_category'

        compareDictType(willIgnoredSysDictTypes);
        // compareDictData(willIgnoredSysDictTypes);
        // compareDictTypeExtension(willIgnoredSysDictTypes);
        // compareDictDataExtension(willIgnoredSysDictTypes);
    }


    @SneakyThrows
    private void compareDictType(Set<String> willIgnoredSysDictTypes) {
        // 获取集中管控系统的字典类型
        List<JzgkSysDictTypeEntity> jzgkSysDictTypeEntityList = jzgkSysDictTypeDbService.list(
                Wrappers
                        .lambdaQuery(JzgkSysDictTypeEntity.class)
                        .notIn(JzgkSysDictTypeEntity::getDictType, willIgnoredSysDictTypes)
                        .orderByAsc(JzgkSysDictTypeEntity::getDictId)
        );
        // 列表转为Map方便操作
        Map<String, JzgkSysDictTypeEntity> jzgkSysDictTypeEntityMapWithDictTypeKey = CollectionUtil.toMap(jzgkSysDictTypeEntityList, new LinkedHashMap<>(), JzgkSysDictTypeEntity::getDictType);

        // 获取智能管控的字典类型
        List<ZngkSysDictTypeEntity> zngkSysDictTypeEntityList = zngkSysDictTypeDbService.list(
                Wrappers
                        .lambdaQuery(ZngkSysDictTypeEntity.class)
                        .notIn(ZngkSysDictTypeEntity::getId, willIgnoredSysDictTypes)
                        .orderByAsc(ZngkSysDictTypeEntity::getId)
        );
        // 列表转为Map方便操作
        Map<String, ZngkSysDictTypeEntity> zngkSysDictTypeEntityMapWithIdKey = CollectionUtil.toMap(zngkSysDictTypeEntityList, new LinkedHashMap<>(), ZngkSysDictTypeEntity::getId);

        List<ChangeSet> changeSetList = new LinkedList<>();

        Date now = new Date();
        Long idBase = now.getTime() / 1000;
        int i = 0;

        // 找出需要新增的
        Collection<String> willAddedKeys = CollectionUtils.subtract(zngkSysDictTypeEntityMapWithIdKey.keySet(), jzgkSysDictTypeEntityMapWithDictTypeKey.keySet());
        if (CollectionUtils.isNotEmpty(willAddedKeys)) {
            for (String willAddedKey : willAddedKeys) {
                i++;
                ZngkSysDictTypeEntity zngkSysDictTypeEntity = zngkSysDictTypeEntityMapWithIdKey.get(willAddedKey);
                String dictId = "%d%03d".formatted(idBase, i);
                ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                changeSet.setComments("sys_dict_type增加%s字典".formatted(zngkSysDictTypeEntity.getId()));
                InsertDataChange change = new InsertDataChange();
                change.setTableName("sys_dict_type");
                change.addColumn(ColumnConfig.fromName("dict_id").setValue(dictId));
                change.addColumn(ColumnConfig.fromName("tenant_id").setValue("000000"));
                change.addColumn(ColumnConfig.fromName("dict_name").setValue(zngkSysDictTypeEntity.getName()));
                change.addColumn(ColumnConfig.fromName("dict_type").setValue(zngkSysDictTypeEntity.getId()));
                change.addColumn(ColumnConfig.fromName("create_dept").setValue("103"));
                change.addColumn(ColumnConfig.fromName("create_by").setValue("1"));
                change.addColumn(ColumnConfig.fromName("create_time").setValue("now()"));
                change.addColumn(ColumnConfig.fromName("remark").setValue(zngkSysDictTypeEntity.getRemark()));
                change.addColumn(ColumnConfig.fromName("use_type").setValue("1"));
                change.addColumn(ColumnConfig.fromName("status").setValue(1 == zngkSysDictTypeEntity.getAvailable() ? "0" : "1"));
                changeSet.addChange(change);
                changeSetList.add(changeSet);
            }
        }

        // 找出需要删除的
        Collection<String> willRemovedKeys = CollectionUtils.subtract(jzgkSysDictTypeEntityMapWithDictTypeKey.keySet(), zngkSysDictTypeEntityMapWithIdKey.keySet());
        if (CollectionUtils.isNotEmpty(willRemovedKeys)) {
            for (String willRemovedKey : willRemovedKeys) {
                i++;
                JzgkSysDictTypeEntity jzgkSysDictTypeEntity = jzgkSysDictTypeEntityMapWithDictTypeKey.get(willRemovedKey);
                // TODO 暂时不删除
                log.warn("发现大数据平台有，但是智能管控系统没有的【字典类型】，暂时不删除：{}", jzgkSysDictTypeEntity);
            }
        }

        // 找出需要对比的
        Collection<String> willComparedKeys = CollectionUtils.intersection(zngkSysDictTypeEntityMapWithIdKey.keySet(), jzgkSysDictTypeEntityMapWithDictTypeKey.keySet());
        if (CollectionUtils.isNotEmpty(willComparedKeys)) {
            for (String willComparedKey : willComparedKeys) {
                ZngkSysDictTypeEntity zngkSysDictTypeEntity = zngkSysDictTypeEntityMapWithIdKey.get(willComparedKey);
                JzgkSysDictTypeEntity jzgkSysDictTypeEntity = jzgkSysDictTypeEntityMapWithDictTypeKey.get(willComparedKey);
                boolean sysDictTypeChanged = false;
                if (!Objects.equals(zngkSysDictTypeEntity.getName(), jzgkSysDictTypeEntity.getDictName())) {
                    jzgkSysDictTypeEntity.setDictName(zngkSysDictTypeEntity.getName());
                    sysDictTypeChanged = true;
                }
                String zngkRemark = zngkSysDictTypeEntity.getRemark() != null ? zngkSysDictTypeEntity.getRemark() : "";
                String jzgkRemark = jzgkSysDictTypeEntity.getRemark() != null ? jzgkSysDictTypeEntity.getRemark() : "";
                if (!Objects.equals(zngkRemark, jzgkRemark)) {
                    jzgkSysDictTypeEntity.setRemark(zngkSysDictTypeEntity.getRemark());
                    sysDictTypeChanged = true;
                }
                String typeStatus = 1 == zngkSysDictTypeEntity.getAvailable() ? "0" : "1";
                if (!Objects.equals(typeStatus, jzgkSysDictTypeEntity.getStatus())) {
                    jzgkSysDictTypeEntity.setStatus(typeStatus);
                    sysDictTypeChanged = true;
                }
                if (sysDictTypeChanged) {
                    i++;
                    ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                    changeSet.setComments("sys_dict_type更新%s字典类型".formatted(zngkSysDictTypeEntity.getName()));
                    UpdateDataChange change = new UpdateDataChange();
                    change.setTableName("sys_dict_type");
                    change.setWhere("dict_id = %d".formatted(jzgkSysDictTypeEntity.getDictId()));
                    change.addColumn(ColumnConfig.fromName("dict_name").setValue(jzgkSysDictTypeEntity.getDictName()));
                    change.addColumn(ColumnConfig.fromName("remark").setValue(jzgkSysDictTypeEntity.getRemark() != null ? jzgkSysDictTypeEntity.getRemark() : ""));
                    change.addColumn(ColumnConfig.fromName("status").setValue(jzgkSysDictTypeEntity.getStatus()));
                    changeSet.addChange(change);
                    changeSetList.add(changeSet);
                }
            }
        }

        // 创建YAML序列化器
        YamlChangeLogSerializer serializer = new YamlChangeLogSerializer();
        try (OutputStream outputStream = new FileOutputStream("dict_type.yml")) {
            serializer.write(changeSetList, outputStream);
        }
    }


    @SneakyThrows
    private void compareDictData(Set<String> willIgnoredSysDictTypes) {
        // 获取集中管控系统的字典数据
        List<JzgkSysDictDataEntity> jzgkSysDictDataEntityList = jzgkSysDictDataDbService.list(
                Wrappers
                        .lambdaQuery(JzgkSysDictDataEntity.class)
                        .notIn(JzgkSysDictDataEntity::getDictType, willIgnoredSysDictTypes)
                        .orderByAsc(JzgkSysDictDataEntity::getDictCode)
        );
        // 列表转为Map方便操作
        Map<String, JzgkSysDictDataEntity> jzgkSysDictDataEntityMapWithDictTypeKey = CollectionUtil.toMap(jzgkSysDictDataEntityList, new LinkedHashMap<>(), JzgkSysDictDataEntity::getBizKey);

        // 获取智能监控系统的字典数据
        List<ZngkSysDictDataEntity> zngkSysDictDataEntityList = zngkSysDictDataDbService.list(
                Wrappers
                        .lambdaQuery(ZngkSysDictDataEntity.class)
                        .notIn(ZngkSysDictDataEntity::getDictionaryTypeId, willIgnoredSysDictTypes)
                        .orderByAsc(ZngkSysDictDataEntity::getId)
        );
        // 列表转为Map方便操作
        Map<String, ZngkSysDictDataEntity> zngkSysDictDataEntityMapWithDictTypeKey = CollectionUtil.toMap(zngkSysDictDataEntityList, new LinkedHashMap<>(), ZngkSysDictDataEntity::getBizKey);

        List<ChangeSet> changeSetList = new LinkedList<>();

        Date now = new Date();
        Long idBase = now.getTime() / 1000;
        int i = 0;

        // 找出需要新增的
        Collection<String> willAddedKeys = CollectionUtils.subtract(zngkSysDictDataEntityMapWithDictTypeKey.keySet(), jzgkSysDictDataEntityMapWithDictTypeKey.keySet());
        if (CollectionUtils.isNotEmpty(willAddedKeys)) {
            for (String willAddedKey : willAddedKeys) {
                i++;
                ZngkSysDictDataEntity zngkSysDictDataEntity = zngkSysDictDataEntityMapWithDictTypeKey.get(willAddedKey);
                ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                changeSet.setComments("sys_dict_data新增%s字典数据".formatted(zngkSysDictDataEntity.getDictionaryTypeId()));
                InsertDataChange change = new InsertDataChange();
                change.setTableName("sys_dict_data");
                change.addColumn(ColumnConfig.fromName("dict_code").setValue(IdUtil.getSnowflakeNextId() + ""));
                change.addColumn(ColumnConfig.fromName("tenant_id").setValue("000000"));
                change.addColumn(ColumnConfig.fromName("dict_sort").setValue(zngkSysDictDataEntity.getSortIndex().toString()));
                change.addColumn(ColumnConfig.fromName("dict_label").setValue(zngkSysDictDataEntity.getName()));
                change.addColumn(ColumnConfig.fromName("dict_value").setValue(zngkSysDictDataEntity.getValue()));
                change.addColumn(ColumnConfig.fromName("dict_type").setValue(zngkSysDictDataEntity.getDictionaryTypeId()));
                change.addColumn(ColumnConfig.fromName("is_default").setValue("0".equals(zngkSysDictDataEntity.getAsDefault().toString()) ? "N" : "Y"));
                change.addColumn(ColumnConfig.fromName("create_dept").setValue("103"));
                change.addColumn(ColumnConfig.fromName("create_by").setValue("1"));
                change.addColumn(ColumnConfig.fromName("create_time").setValue("now()"));
                change.addColumn(ColumnConfig.fromName("remark").setValue(zngkSysDictDataEntity.getRemark()));
                changeSet.addChange(change);
                changeSetList.add(changeSet);
            }
        }

        // 找出需要删除的
        Collection<String> willRemovedKeys = CollectionUtils.subtract(jzgkSysDictDataEntityMapWithDictTypeKey.keySet(), zngkSysDictDataEntityMapWithDictTypeKey.keySet());
        if (CollectionUtils.isNotEmpty(willRemovedKeys)) {
            for (String willRemovedKey : willRemovedKeys) {
                i++;
                JzgkSysDictDataEntity jzgkSysDictDataEntity = jzgkSysDictDataEntityMapWithDictTypeKey.get(willRemovedKey);
                // TODO 暂时不删除
                log.warn("发现大数据平台有，但是智能管控系统没有的【字典数据】，暂时不删除：{}", jzgkSysDictDataEntity);
            }
        }

        // 找出需要对比的
        Collection<String> willComparedKeys = CollectionUtils.intersection(zngkSysDictDataEntityMapWithDictTypeKey.keySet(), jzgkSysDictDataEntityMapWithDictTypeKey.keySet());
        if (CollectionUtils.isNotEmpty(willComparedKeys)) {
            for (String willComparedKey : willComparedKeys) {
                ZngkSysDictDataEntity zngkSysDictDataEntity = zngkSysDictDataEntityMapWithDictTypeKey.get(willComparedKey);
                JzgkSysDictDataEntity jzgkSysDictDataEntity = jzgkSysDictDataEntityMapWithDictTypeKey.get(willComparedKey);
                boolean sysDictDataChanged = false;
                if (!Objects.equals(zngkSysDictDataEntity.getName(), jzgkSysDictDataEntity.getDictLabel())) {
                    jzgkSysDictDataEntity.setDictLabel(zngkSysDictDataEntity.getName());
                    sysDictDataChanged = true;
                }
                String zngkRemark = zngkSysDictDataEntity.getRemark() != null ? zngkSysDictDataEntity.getRemark() : "";
                String jzgkRemark = jzgkSysDictDataEntity.getRemark() != null ? jzgkSysDictDataEntity.getRemark() : "";
                if (!Objects.equals(zngkRemark, jzgkRemark)) {
                    jzgkSysDictDataEntity.setRemark(jzgkRemark);
                    sysDictDataChanged = true;
                }
                if (!Objects.equals(zngkSysDictDataEntity.getSortIndex(), jzgkSysDictDataEntity.getDictSort())) {
                    jzgkSysDictDataEntity.setDictSort(zngkSysDictDataEntity.getSortIndex());
                    sysDictDataChanged = true;
                }
                String isDefault = 0 == zngkSysDictDataEntity.getAsDefault() ? "N" : "Y";
                if (!Objects.equals(isDefault, jzgkSysDictDataEntity.getIsDefault())) {
                    jzgkSysDictDataEntity.setIsDefault(isDefault);
                    sysDictDataChanged = true;
                }
                String dataStatus = 1 == zngkSysDictDataEntity.getAvailable() ? "0" : "1";
                if (!Objects.equals(dataStatus, jzgkSysDictDataEntity.getStatus())) {
                    jzgkSysDictDataEntity.setStatus(dataStatus);
                    sysDictDataChanged = true;
                }
                if (sysDictDataChanged) {
                    i++;
                    ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                    changeSet.setComments("sys_dict_data更新%s字典数据".formatted(jzgkSysDictDataEntity.getDictType()));
                    UpdateDataChange updateDictTypeChange = new UpdateDataChange();
                    updateDictTypeChange.setTableName("sys_dict_data");
                    updateDictTypeChange.setWhere("dict_code = %d".formatted(jzgkSysDictDataEntity.getDictCode()));
                    updateDictTypeChange.addColumn(ColumnConfig.fromName("dict_sort").setValue(jzgkSysDictDataEntity.getDictSort() + ""));
                    updateDictTypeChange.addColumn(ColumnConfig.fromName("dict_label").setValue(jzgkSysDictDataEntity.getDictLabel() != null ? jzgkSysDictDataEntity.getDictLabel() : ""));
                    updateDictTypeChange.addColumn(ColumnConfig.fromName("is_default").setValue(jzgkSysDictDataEntity.getIsDefault()));
                    updateDictTypeChange.addColumn(ColumnConfig.fromName("remark").setValue(jzgkSysDictDataEntity.getRemark() != null ? jzgkSysDictDataEntity.getRemark() : ""));
                    updateDictTypeChange.addColumn(ColumnConfig.fromName("status").setValue(jzgkSysDictDataEntity.getStatus()));
                    changeSet.addChange(updateDictTypeChange);
                    changeSetList.add(changeSet);
                }
            }
        }

        // 创建YAML序列化器
        YamlChangeLogSerializer serializer = new YamlChangeLogSerializer();
        try (OutputStream outputStream = new FileOutputStream("dict_data.yml")) {
            serializer.write(changeSetList, outputStream);
        }
    }


    @SneakyThrows
    private void compareDictTypeExtension(Set<String> willIgnoredSysDictTypes) {
        // 获取集中管控系统的字典类型拓展
        List<JzgkSysDictTypeExtensionEntity> jzgkSysDictTypeExtensionEntityList = jzgkSysDictTypeExtensionDbService.list(
                Wrappers
                        .lambdaQuery(JzgkSysDictTypeExtensionEntity.class)
                        .notIn(JzgkSysDictTypeExtensionEntity::getDictType, willIgnoredSysDictTypes)
                        .orderByAsc(JzgkSysDictTypeExtensionEntity::getId)
        );
        // 列表转为Map方便操作
        Map<String, JzgkSysDictTypeExtensionEntity> jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey = CollectionUtil.toMap(jzgkSysDictTypeExtensionEntityList, new LinkedHashMap<>(), JzgkSysDictTypeExtensionEntity::getBizKey);

        // 获取智能管控的字典类型拓展
        List<ZngkSysDictTypeExtensionEntity> zngkSysDictTypeExtensionEntityList = zngkSysDictTypeExtensionDbService.list(
                Wrappers
                        .lambdaQuery(ZngkSysDictTypeExtensionEntity.class)
                        .notIn(ZngkSysDictTypeExtensionEntity::getDictionaryTypeId, willIgnoredSysDictTypes)
                        .orderByAsc(ZngkSysDictTypeExtensionEntity::getId)
        );
        // 列表转为Map方便操作
        Map<String, ZngkSysDictTypeExtensionEntity> zngkSysDictTypeExtensionEntityMapWithIdKey = CollectionUtil.toMap(zngkSysDictTypeExtensionEntityList, new LinkedHashMap<>(), ZngkSysDictTypeExtensionEntity::getBizKey);

        List<ChangeSet> changeSetList = new LinkedList<>();

        Date now = new Date();
        Long idBase = now.getTime() / 1000;
        int i = 0;

        // 找出需要新增的
        Collection<String> willAddedKeys = CollectionUtils.subtract(zngkSysDictTypeExtensionEntityMapWithIdKey.keySet(), jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey.keySet());
        if (CollectionUtils.isNotEmpty(willAddedKeys)) {
            for (String willAddedKey : willAddedKeys) {
                i++;
                ZngkSysDictTypeExtensionEntity zngkSysDictTypeExtensionEntity = zngkSysDictTypeExtensionEntityMapWithIdKey.get(willAddedKey);
                ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                changeSet.setComments("sys_dict_type_extension新增%s字典类型拓展".formatted(zngkSysDictTypeExtensionEntity.getBizKey()));
                InsertDataChange insertDictDataChange = new InsertDataChange();
                insertDictDataChange.setTableName("sys_dict_type_extension");
                insertDictDataChange.addColumn(ColumnConfig.fromName("id").setValue(IdUtil.getSnowflakeNextId() + ""));
                insertDictDataChange.addColumn(ColumnConfig.fromName("dict_type").setValue(zngkSysDictTypeExtensionEntity.getDictionaryTypeId()));
                insertDictDataChange.addColumn(ColumnConfig.fromName("data_type").setValue(zngkSysDictTypeExtensionEntity.getDataType() + ""));
                insertDictDataChange.addColumn(ColumnConfig.fromName("data_key").setValue(zngkSysDictTypeExtensionEntity.getDataKey()));
                insertDictDataChange.addColumn(ColumnConfig.fromName("remark").setValue(zngkSysDictTypeExtensionEntity.getRemark() != null ? zngkSysDictTypeExtensionEntity.getRemark() : ""));
                changeSet.addChange(insertDictDataChange);
                changeSetList.add(changeSet);
            }
        }

        // 找出需要删除的
        Collection<String> willRemovedKeys = CollectionUtils.subtract(jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey.keySet(), zngkSysDictTypeExtensionEntityMapWithIdKey.keySet());
        if (CollectionUtils.isNotEmpty(willRemovedKeys)) {
            for (String willRemovedKey : willRemovedKeys) {
                i++;
                JzgkSysDictTypeExtensionEntity jzgkSysDictTypeExtensionEntity = jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey.get(willRemovedKey);
                // TODO 暂时不删除
                log.warn("发现大数据平台有，但是智能管控系统没有的【字典类型拓展】，暂时不删除：{}", jzgkSysDictTypeExtensionEntity);
            }
        }

        // 找出需要对比的
        Collection<String> willComparedKeys = CollectionUtils.intersection(zngkSysDictTypeExtensionEntityMapWithIdKey.keySet(), jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey.keySet());
        if (CollectionUtils.isNotEmpty(willComparedKeys)) {
            for (String willComparedKey : willComparedKeys) {
                ZngkSysDictTypeExtensionEntity zngkSysDictTypeExtensionEntity = zngkSysDictTypeExtensionEntityMapWithIdKey.get(willComparedKey);
                JzgkSysDictTypeExtensionEntity jzgkSysDictTypeExtensionEntity = jzgkSysDictTypeExtensionEntityMapWithDictTypeExtensionKey.get(willComparedKey);
                boolean dictTypeExtensionChanged = false;
                if (!Objects.equals(jzgkSysDictTypeExtensionEntity.getDataType(), zngkSysDictTypeExtensionEntity.getDataType().toString())) {
                    jzgkSysDictTypeExtensionEntity.setDataType(zngkSysDictTypeExtensionEntity.getDataType().toString());
                    dictTypeExtensionChanged = true;
                }
                if (!Objects.equals(jzgkSysDictTypeExtensionEntity.getDataKey(), zngkSysDictTypeExtensionEntity.getDataKey())) {
                    jzgkSysDictTypeExtensionEntity.setDataKey(zngkSysDictTypeExtensionEntity.getDataKey());
                    dictTypeExtensionChanged = true;
                }
                String jzgkRemark = jzgkSysDictTypeExtensionEntity.getRemark() != null ? jzgkSysDictTypeExtensionEntity.getRemark() : "";
                String zngkRemark = zngkSysDictTypeExtensionEntity.getRemark() != null ? zngkSysDictTypeExtensionEntity.getRemark() : "";
                if (!Objects.equals(jzgkRemark, zngkRemark)) {
                    jzgkSysDictTypeExtensionEntity.setRemark(zngkSysDictTypeExtensionEntity.getRemark());
                    dictTypeExtensionChanged = true;
                }
                if (dictTypeExtensionChanged) {
                    i++;
                    ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                    changeSet.setComments("sys_dict_type_extension更新%s字典类型拓展".formatted(zngkSysDictTypeExtensionEntity.getBizKey()));
                    UpdateDataChange updateDataChange = new UpdateDataChange();
                    updateDataChange.setTableName("sys_dict_type_extension");
                    updateDataChange.setWhere("id = %d".formatted(jzgkSysDictTypeExtensionEntity.getId()));
                    updateDataChange.addColumn(ColumnConfig.fromName("data_type").setValue(jzgkSysDictTypeExtensionEntity.getDataType()));
                    updateDataChange.addColumn(ColumnConfig.fromName("data_key").setValue(jzgkSysDictTypeExtensionEntity.getDataKey()));
                    updateDataChange.addColumn(ColumnConfig.fromName("remark").setValue(jzgkSysDictTypeExtensionEntity.getRemark() != null ? jzgkSysDictTypeExtensionEntity.getRemark() : ""));
                    changeSet.addChange(updateDataChange);
                    changeSetList.add(changeSet);
                }
            }
        }

        // 创建YAML序列化器
        YamlChangeLogSerializer serializer = new YamlChangeLogSerializer();
        try (OutputStream outputStream = new FileOutputStream("dict_type_extension.yml")) {
            serializer.write(changeSetList, outputStream);
        }
    }


    @SneakyThrows
    private void compareDictDataExtension(Set<String> willIgnoredSysDictTypes) {
        // 获取集中管控系统的字典数据拓展
        List<JzgkSysDictDataExtensionEntity> jzgkSysDictDataExtensionEntityList = jzgkSysDictDataExtensionDbService.list(
                Wrappers
                        .lambdaQuery(JzgkSysDictDataExtensionEntity.class)
                        .notIn(JzgkSysDictDataExtensionEntity::getDictType, willIgnoredSysDictTypes)
                        .orderByAsc(JzgkSysDictDataExtensionEntity::getId)
        );
        // 列表转为Map方便操作
        Map<String, JzgkSysDictDataExtensionEntity> jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey = CollectionUtil.toMap(jzgkSysDictDataExtensionEntityList, new LinkedHashMap<>(), JzgkSysDictDataExtensionEntity::getBizKey);

        // 获取智能监控系统的字典数据
        List<ZngkSysDictDataEntity> zngkSysDictDataEntityList = zngkSysDictDataDbService.list(
                Wrappers
                        .lambdaQuery(ZngkSysDictDataEntity.class)
                        .notIn(ZngkSysDictDataEntity::getDictionaryTypeId, willIgnoredSysDictTypes)
                        .orderByAsc(ZngkSysDictDataEntity::getId)
        );
        // 列表转为Map方便操作
        Map<Long, ZngkSysDictDataEntity> zngkSysDictDataEntityMapWithIdKey = CollectionUtil.toMap(zngkSysDictDataEntityList, new LinkedHashMap<>(), ZngkSysDictDataEntity::getId);

        Set<Long> zngkSysDictDataIds = zngkSysDictDataEntityList.stream().filter(Objects::nonNull).map(ZngkSysDictDataEntity::getId).filter(Objects::nonNull).collect(Collectors.toSet());
        // 获取智能管控的字典数据拓展
        List<ZngkSysDictDataExtensionEntity> zngkSysDictDataExtensionEntityList = zngkSysDictDataExtensionDbService.list(
                Wrappers
                        .lambdaQuery(ZngkSysDictDataExtensionEntity.class)
                        .in(ZngkSysDictDataExtensionEntity::getDictionaryValueId, zngkSysDictDataIds)
                        .orderByAsc(ZngkSysDictDataExtensionEntity::getId)
        );

        for (ZngkSysDictDataExtensionEntity zngkSysDictDataExtensionEntity : zngkSysDictDataExtensionEntityList) {
            ZngkSysDictDataEntity zngkSysDictDataEntity = zngkSysDictDataEntityMapWithIdKey.get(zngkSysDictDataExtensionEntity.getDictionaryValueId());
            zngkSysDictDataExtensionEntity.setDictionaryTypeId(zngkSysDictDataEntity.getDictionaryTypeId());
            zngkSysDictDataExtensionEntity.setDictionaryValue(zngkSysDictDataEntity.getValue());
        }

        // 列表转为Map方便操作
        Map<String, ZngkSysDictDataExtensionEntity> zngkSysDictDataExtensionEntityMapWithIdKey = CollectionUtil.toMap(zngkSysDictDataExtensionEntityList, new LinkedHashMap<>(), ZngkSysDictDataExtensionEntity::getBizKey);

        List<ChangeSet> changeSetList = new LinkedList<>();

        Date now = new Date();
        Long idBase = now.getTime() / 1000;
        int i = 0;

        // 找出需要新增的
        Collection<String> willAddedKeys = CollectionUtils.subtract(zngkSysDictDataExtensionEntityMapWithIdKey.keySet(), jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey.keySet());
        if (CollectionUtils.isNotEmpty(willAddedKeys)) {
            for (String willAddedKey : willAddedKeys) {
                i++;
                ZngkSysDictDataExtensionEntity zngkSysDictDataExtensionEntity = zngkSysDictDataExtensionEntityMapWithIdKey.get(willAddedKey);
                ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                changeSet.setComments("sys_dict_data_extension新增%s字典数据拓展".formatted(zngkSysDictDataExtensionEntity.getBizKey()));
                InsertDataChange change = new InsertDataChange();
                change.setTableName("sys_dict_data_extension");
                change.addColumn(ColumnConfig.fromName("id").setValue(IdUtil.getSnowflakeNextId() + ""));
                change.addColumn(ColumnConfig.fromName("dict_type").setValue(zngkSysDictDataExtensionEntity.getDictionaryTypeId()));
                change.addColumn(ColumnConfig.fromName("dict_value").setValue(zngkSysDictDataExtensionEntity.getDictionaryValue()));
                change.addColumn(ColumnConfig.fromName("data_type").setValue(zngkSysDictDataExtensionEntity.getDataType() + ""));
                change.addColumn(ColumnConfig.fromName("data_key").setValue(zngkSysDictDataExtensionEntity.getDataKey()));
                change.addColumn(ColumnConfig.fromName("data_value").setValue(zngkSysDictDataExtensionEntity.getDataValue()));
                changeSet.addChange(change);
                changeSetList.add(changeSet);
            }
        }

        // 找出需要删除的
        Collection<String> willRemovedKeys = CollectionUtils.subtract(jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey.keySet(), zngkSysDictDataExtensionEntityMapWithIdKey.keySet());
        if (CollectionUtils.isNotEmpty(willRemovedKeys)) {
            for (String willRemovedKey : willRemovedKeys) {
                i++;
                JzgkSysDictDataExtensionEntity jzgkSysDictDataExtensionEntity = jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey.get(willRemovedKey);
                // TODO 暂时不删除
                log.warn("发现大数据平台有，但是智能管控系统没有的【字典数据拓展】，暂时不删除：{}", jzgkSysDictDataExtensionEntity);
            }
        }

        // 找出需要对比的
        Collection<String> willComparedKeys = CollectionUtils.intersection(zngkSysDictDataExtensionEntityMapWithIdKey.keySet(), jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey.keySet());
        if (CollectionUtils.isNotEmpty(willComparedKeys)) {
            for (String willComparedKey : willComparedKeys) {
                ZngkSysDictDataExtensionEntity zngkSysDictDataExtensionEntity = zngkSysDictDataExtensionEntityMapWithIdKey.get(willComparedKey);
                JzgkSysDictDataExtensionEntity jzgkSysDictDataExtensionEntity = jzgkSysDictDataExtensionEntityMapWithDictDataExtensionKey.get(willComparedKey);
                boolean dictDataExtensionChanged = false;
                if (!Objects.equals(jzgkSysDictDataExtensionEntity.getDataType(), zngkSysDictDataExtensionEntity.getDataType().toString())) {
                    jzgkSysDictDataExtensionEntity.setDataType(zngkSysDictDataExtensionEntity.getDataType().toString());
                    dictDataExtensionChanged = true;
                }
                if (!Objects.equals(jzgkSysDictDataExtensionEntity.getDataValue(), zngkSysDictDataExtensionEntity.getDataValue())) {
                    jzgkSysDictDataExtensionEntity.setDataValue(zngkSysDictDataExtensionEntity.getDataValue());
                    dictDataExtensionChanged = true;
                }
                if (dictDataExtensionChanged) {
                    i++;
                    ChangeSet changeSet = new ChangeSet(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmm-%02d".formatted(i))), "周立山", false, false, null, null, null, true, null);
                    changeSet.setComments("sys_dict_data_extension更新%s字典数据拓展".formatted(zngkSysDictDataExtensionEntity.getBizKey()));
                    UpdateDataChange updateDataChange = new UpdateDataChange();
                    updateDataChange.setTableName("sys_dict_data_extension");
                    updateDataChange.setWhere("id = %d".formatted(jzgkSysDictDataExtensionEntity.getId()));
                    updateDataChange.addColumn(ColumnConfig.fromName("data_type").setValue(jzgkSysDictDataExtensionEntity.getDataType()));
                    updateDataChange.addColumn(ColumnConfig.fromName("data_value").setValue(jzgkSysDictDataExtensionEntity.getDataValue()));
                    changeSet.addChange(updateDataChange);
                    changeSetList.add(changeSet);
                }
            }
        }

        // 创建YAML序列化器
        YamlChangeLogSerializer serializer = new YamlChangeLogSerializer();
        try (OutputStream outputStream = new FileOutputStream("dict_data_extension.yml")) {
            serializer.write(changeSetList, outputStream);
        }
    }

}
